package model;

/**
 * Character models a game entity, be it human or AI controlled,
 * that resides in and can move around a Maze.   This class has methods
 * to move around the maze and to access the maze's tiles. Inheriting
 * classes can implement specific behaviour or characteristics.
 * @author Alex Dinardo, Alexander Craig
 *
 */
public abstract class Character {

	/** A reference to the Tile that the Character is occupying.*/
	private Tile currentTile;
	
	/** The direction of the characters last movement */
	private Direction lastMove;
	
	/**
	 * Constructor of objects of type Character.
	 * @param startTile The tile that the Character is placed in at the start of every level. 
	 */
	public Character(Tile startTile)
	{
		currentTile = startTile;
		lastMove = null;
	}
	
	/**
	 * @return	the direction of the characters last move, or null if the character
	 * 			has not moved since being created
	 */
	public Direction getLastMove() {
		return lastMove;
	}
	
	/**
	 * Sets the character last move to the specified direction. Useful for
	 * path finding algorithms that return a tile instead of a direction.
	 * @param d	the direction to set the last move to
	 */
	public void setLastMove(Direction d) {
		lastMove = d;
	}
	
	/**
	 * Moves the Character one Tile in the desired Direction.
	 * @param dir The Direction that the Character needs to move in.
	 * @return True if the move was a success. False if it failed (ie. there
	 * is no exit in the Direction.
	 */
	public boolean move(Direction dir)
	{
		boolean success = setTile(getNeighbour(dir));
		if (success) {
			lastMove = dir;
		} else {
			lastMove = null;
		}
		return success;
	}
	
	/**
	 * Gets the Tile adjacent to this Character's current Tile
	 * in the desired Direction.
	 * @param dir The Direction to search for an adjacent Tile.
	 * @return The Tile that the exit in that Direction leads to.
	 * 			Returns null if the exit contains a null reference (a wall
	 * 			in the Maze).
	 */
	public Tile getNeighbour(Direction dir)
	{
		return currentTile.getExit(dir);
	}
	
	/**
	 * Sets a new Tile as the Character's current position, provided the tile
	 * is not null. If the tile is null, nothing occurs and false is returned.
	 * @param newTile 
	 * @return True if successful.
	 */
	public boolean setTile (Tile newTile)
	{
		if(newTile != null){
			currentTile = newTile;
			return true;
		}
		return false;
	}
	
	/**
	 * Gets the tile that the Character currently resides in.
	 * @return The current tile.
	 */
	public Tile getTile()
	{
		return currentTile;
	}
}
